package com.example.filter;

import com.auth0.jwt.interfaces.DecodedJWT;
import com.example.utils.Const;
import com.example.utils.JwtUtils;
import jakarta.annotation.Resource;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;

/**
 * 作者:xuSen
 * 日期2025/4/13 14:35
 */
@Component
public class jwtAuthorizeFiler extends OncePerRequestFilter {
    @Resource
    private JwtUtils jwtUtils;
    /**
     * 执行实际的过滤逻辑
     */
    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
        // 从请求头中获取授权信息
        String authorization = request.getHeader("Authorization");
        // 解析JWT令牌
        DecodedJWT jwt = jwtUtils.resoleJwt(authorization);
        if(jwt!=null){
            // 将JWT中的用户信息转换为UserDetails对象
            UserDetails user = jwtUtils.toUserDetails(jwt);
            // 创建认证令牌对象，包含用户信息和权限
            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(user,null,user.getAuthorities());
            // 设置认证令牌的详细信息，如远程地址等
            authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
            // 将认证信息存储在SecurityContext中，以便Spring Security使用
            SecurityContextHolder.getContext().setAuthentication(authentication);
            // 在请求属性中设置用户ID，以便后续处理使用
            request.setAttribute(Const.ATTR_USER_ID,jwtUtils.toId(jwt));
        }
        // 继续执行过滤链中的下一个过滤器或目标资源
        filterChain.doFilter(request,response);
    }
}
